package calvin.study.redis.config;

import java.io.Serializable;
import java.net.UnknownHostException;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;

import calvin.study.middle.utils.RedisUtil;

@Configuration
public class RedisConfig {

	/*
	 * 自定义RedisTemplate
	 */
	@Bean(name="redisTemplate")
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<String, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		// Json序列化配置
		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
		// 该方法是指定序列化输入的类型，就是将数据库里的数据按照一定类型存储到redis缓存中。
		// om.enableDefaultTyping(DefaultTyping.NON_FINAL);
		om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,As.WRAPPER_ARRAY);
		jackson2JsonRedisSerializer.setObjectMapper(om);

		StringRedisSerializer strRedsSerializer = new StringRedisSerializer();

		// key采用String的序列化方式
		template.setKeySerializer(strRedsSerializer);
		// hash的key也采用String的序列化方式
		template.setHashKeySerializer(strRedsSerializer);
		// value序列化方式采用jackson
		template.setValueSerializer(jackson2JsonRedisSerializer);
		template.setHashValueSerializer(jackson2JsonRedisSerializer);
		template.afterPropertiesSet();
		return template;
	}
	
	@Bean
	public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
		return new RedisUtil(redisTemplate);
	}
	
	
	public RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory connectionFactory)
			throws UnknownHostException {
		RedisTemplate<String, Serializable> template = new RedisTemplate<>();
		template.setConnectionFactory(connectionFactory);

		StringRedisSerializer strRedsSerializer = new StringRedisSerializer();
		// key采用String的序列化方式
		template.setKeySerializer(strRedsSerializer);
		template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
		return template;
	}
	

}
